package com.snack.shop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.snack.shop.dto.HotProductDTO;
import com.snack.shop.dto.MerchantStatsDTO;
import com.snack.shop.entity.Order;
import com.snack.shop.entity.OrderItem;
import com.snack.shop.entity.Product;
import com.snack.shop.mapper.OrderItemMapper;
import com.snack.shop.mapper.OrderMapper;
import com.snack.shop.mapper.ProductMapper;
import com.snack.shop.service.MerchantService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 商家服务实现
 */
@Service
@RequiredArgsConstructor
public class MerchantServiceImpl implements MerchantService {

    private final OrderMapper orderMapper;
    private final OrderItemMapper orderItemMapper;
    private final ProductMapper productMapper;

    @Override
    public MerchantStatsDTO getStats(String timeRange) {
        LocalDateTime startTime = getStartTime(timeRange);
        
        MerchantStatsDTO stats = new MerchantStatsDTO();
        
        // 查询所有订单数据
        LambdaQueryWrapper<Order> orderWrapper = new LambdaQueryWrapper<>();
        if (startTime != null) {
            orderWrapper.ge(Order::getCreateTime, startTime);
        }
        List<Order> allOrders = orderMapper.selectList(orderWrapper);
        
        // ========== 零食订单统计 ==========
        List<Order> snackOrders = allOrders.stream()
            .filter(o -> o.getOrderType() == 1)
            .collect(Collectors.toList());
        
        // 零食订单各状态统计（使用统一状态v2.0）
        stats.setSnackPendingOrders((int) snackOrders.stream().filter(o -> o.getStatus() == 1).count());
        stats.setSnackDeliveringOrders((int) snackOrders.stream().filter(o -> o.getStatus() == 3).count());
        stats.setSnackCompletedOrders((int) snackOrders.stream().filter(o -> o.getStatus() == 6).count());
        stats.setSnackCancelledOrders((int) snackOrders.stream().filter(o -> o.getStatus() == 7 || o.getStatus() == 8).count());
        
        // 零食已完成订单
        List<Order> snackCompleted = snackOrders.stream()
            .filter(o -> o.getStatus() == 6)
            .collect(Collectors.toList());
        
        stats.setSnackTotalOrders(snackCompleted.size());
        
        // 零食总销售额
        BigDecimal snackTotalSales = snackCompleted.stream()
            .map(Order::getActualAmount)
            .reduce(BigDecimal.ZERO, BigDecimal::add);
        stats.setSnackTotalSales(snackTotalSales);
        
        // 零食购买用户数（去重）
        Set<Long> snackUserIds = snackCompleted.stream()
            .map(Order::getUserId)
            .collect(Collectors.toSet());
        stats.setSnackTotalUsers(snackUserIds.size());
        
        // 零食客单价
        if (snackCompleted.size() > 0) {
            BigDecimal snackAvgPrice = snackTotalSales.divide(
                new BigDecimal(snackCompleted.size()), 
                2, 
                RoundingMode.HALF_UP
            );
            stats.setSnackAvgPrice(snackAvgPrice);
        } else {
            stats.setSnackAvgPrice(BigDecimal.ZERO);
        }
        
        // ========== 代取订单统计 ==========
        List<Order> pickupOrders = allOrders.stream()
            .filter(o -> o.getOrderType() == 2 || o.getOrderType() == 3 || o.getOrderType() == 4)
            .collect(Collectors.toList());
        
        // 代取订单各状态统计（使用统一状态v2.0）
        stats.setPickupPendingOrders((int) pickupOrders.stream().filter(o -> o.getStatus() == 1).count());
        stats.setPickupInProgressOrders((int) pickupOrders.stream()
            .filter(o -> o.getStatus() == 2 || o.getStatus() == 3 || o.getStatus() == 4)
            .count());
        // 待结算数量：包含正常待结算(status=5 且 settlementStatus=1)与退款补偿待结算(status=8 且 settlementStatus=1 且 compensation>0)
        stats.setPickupWaitingSettlement((int) pickupOrders.stream()
            .filter(o -> o.getSettlementStatus() != null && o.getSettlementStatus() == 1
                && (o.getStatus() == 5 || (o.getStatus() == 8 && o.getCompensationAmount() != null && o.getCompensationAmount().compareTo(BigDecimal.ZERO) > 0)))
            .count());
        stats.setPickupCompletedOrders((int) pickupOrders.stream().filter(o -> o.getStatus() == 6).count());
        
        // 代取订单总数（所有已支付的订单）
        List<Order> pickupPaid = pickupOrders.stream()
            .filter(o -> o.getStatus() != 0 && o.getStatus() != 7 && o.getStatus() != 8)
            .collect(Collectors.toList());
        stats.setPickupTotalOrders(pickupPaid.size());
        
        // 代取订单总金额
        BigDecimal pickupTotalAmount = pickupPaid.stream()
            .map(Order::getActualAmount)
            .reduce(BigDecimal.ZERO, BigDecimal::add);
        stats.setPickupTotalAmount(pickupTotalAmount);
        
        // 代取平台服务费收入（已完成和待结算的订单；退款订单不计平台费）
        BigDecimal pickupPlatformFee = pickupOrders.stream()
            .filter(o -> o.getStatus() == 5 || o.getStatus() == 6)
            .map(o -> o.getPlatformFee() != null ? o.getPlatformFee() : BigDecimal.ZERO)
            .reduce(BigDecimal.ZERO, BigDecimal::add);
        stats.setPickupPlatformFee(pickupPlatformFee);
        
        // 代取待结算金额（商家需支付给接单人）：包含正常待结算与退款补偿结算中
        BigDecimal pickupPendingSettlement = pickupOrders.stream()
            .filter(o -> o.getSettlementStatus() != null && o.getSettlementStatus() == 1
                && (o.getStatus() == 5 || (o.getStatus() == 8 && o.getCompensationAmount() != null && o.getCompensationAmount().compareTo(BigDecimal.ZERO) > 0)))
            .map(o -> o.getRiderEarning() != null ? o.getRiderEarning() : BigDecimal.ZERO)
            .reduce(BigDecimal.ZERO, BigDecimal::add);
        stats.setPickupPendingSettlement(pickupPendingSettlement);
        
        // 代取已结算金额（包含退款补偿已结算）
        BigDecimal pickupSettledAmount = pickupOrders.stream()
            .filter(o -> o.getSettlementStatus() == 2)
            .map(o -> o.getRiderEarning() != null ? o.getRiderEarning() : BigDecimal.ZERO)
            .reduce(BigDecimal.ZERO, BigDecimal::add);
        stats.setPickupSettledAmount(pickupSettledAmount);
        
        // ========== 代取退款与补偿统计 ==========
        // 已退款订单（聚合：所有订单 status=8）
        int refundedOrdersAgg = (int) allOrders.stream()
            .filter(o -> o.getStatus() == 8)
            .count();
        stats.setPickupRefundedOrders(refundedOrdersAgg);

        int pickupRefundCompensationOrders = (int) pickupOrders.stream()
            .filter(o -> o.getStatus() == 8 && o.getCompensationAmount() != null && o.getCompensationAmount().compareTo(BigDecimal.ZERO) > 0)
            .count();
        stats.setPickupRefundCompensationOrders(pickupRefundCompensationOrders);

        // 退款总金额（聚合：所有订单 status=8）
        BigDecimal refundTotalAmountAgg = allOrders.stream()
            .filter(o -> o.getStatus() == 8)
            .map(o -> o.getRefundAmount() != null ? o.getRefundAmount() : BigDecimal.ZERO)
            .reduce(BigDecimal.ZERO, BigDecimal::add);
        stats.setPickupRefundTotalAmount(refundTotalAmountAgg);

        BigDecimal pickupCompensationTotal = pickupOrders.stream()
            .filter(o -> o.getCompensationAmount() != null && o.getCompensationAmount().compareTo(BigDecimal.ZERO) > 0)
            .map(Order::getCompensationAmount)
            .reduce(BigDecimal.ZERO, BigDecimal::add);
        stats.setPickupCompensationTotal(pickupCompensationTotal);

        BigDecimal pickupCompensationPendingSettlement = pickupOrders.stream()
            .filter(o -> o.getStatus() == 8 && o.getSettlementStatus() != null && o.getSettlementStatus() == 1
                && o.getCompensationAmount() != null && o.getCompensationAmount().compareTo(BigDecimal.ZERO) > 0)
            .map(o -> o.getRiderEarning() != null ? o.getRiderEarning() : BigDecimal.ZERO)
            .reduce(BigDecimal.ZERO, BigDecimal::add);
        stats.setPickupCompensationPendingSettlement(pickupCompensationPendingSettlement);

        BigDecimal pickupCompensationSettledAmount = pickupOrders.stream()
            .filter(o -> o.getStatus() == 8 && o.getSettlementStatus() != null && o.getSettlementStatus() == 2
                && o.getCompensationAmount() != null && o.getCompensationAmount().compareTo(BigDecimal.ZERO) > 0)
            .map(o -> o.getRiderEarning() != null ? o.getRiderEarning() : BigDecimal.ZERO)
            .reduce(BigDecimal.ZERO, BigDecimal::add);
        stats.setPickupCompensationSettledAmount(pickupCompensationSettledAmount);
        
        // ========== 订单统计汇总（零食+代取） ==========
        int aggPending = (int) snackOrders.stream().filter(o -> o.getStatus() == 1).count()
            + (int) pickupOrders.stream().filter(o -> o.getStatus() == 1).count();
        int aggDelivering = (int) snackOrders.stream().filter(o -> o.getStatus() == 3).count()
            + (int) pickupOrders.stream().filter(o -> o.getStatus() == 2 || o.getStatus() == 3 || o.getStatus() == 4).count();
        int aggCompleted = (int) snackOrders.stream().filter(o -> o.getStatus() == 6).count()
            + (int) pickupOrders.stream().filter(o -> o.getStatus() == 6).count();
        int aggCancelled = (int) snackOrders.stream().filter(o -> o.getStatus() == 7 || o.getStatus() == 8).count()
            + (int) pickupOrders.stream().filter(o -> o.getStatus() == 7 || o.getStatus() == 8).count();

        stats.setPendingOrders(aggPending);
        stats.setDeliveringOrders(aggDelivering);
        stats.setCompletedOrders(aggCompleted);
        stats.setCancelledOrders(aggCancelled);

        // ========== 总计统计 ==========
        stats.setTotalSales(snackTotalSales.add(pickupTotalAmount));
        stats.setTotalOrders(snackCompleted.size() + pickupPaid.size());
        // 顶层汇总补充：购买用户与客单价（按零食数据口径，与前端卡片字段对齐）
        stats.setTotalUsers(snackUserIds.size());
        stats.setAvgPrice(stats.getSnackAvgPrice());
        
        return stats;
    }

    @Override
    public List<HotProductDTO> getHotProducts(String timeRange, Integer limit) {
        LocalDateTime startTime = getStartTime(timeRange);
        
        // 查询已完成的零食订单（使用统一状态v2.0）
        LambdaQueryWrapper<Order> orderWrapper = new LambdaQueryWrapper<>();
        orderWrapper.eq(Order::getOrderType, 1) // 只统计零食订单
                   .eq(Order::getStatus, 6); // 已完成
        if (startTime != null) {
            orderWrapper.ge(Order::getCreateTime, startTime);
        }
        
        List<Order> completedOrders = orderMapper.selectList(orderWrapper);
        
        if (completedOrders.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 获取订单ID列表
        List<Long> orderIds = completedOrders.stream()
            .map(Order::getId)
            .collect(Collectors.toList());
        
        // 查询订单商品明细
        LambdaQueryWrapper<OrderItem> itemWrapper = new LambdaQueryWrapper<>();
        itemWrapper.in(OrderItem::getOrderId, orderIds);
        List<OrderItem> orderItems = orderItemMapper.selectList(itemWrapper);
        
        // 按商品ID分组统计
        Map<Long, HotProductDTO> productStatsMap = new HashMap<>();
        
        for (OrderItem item : orderItems) {
            Long productId = item.getProductId();
            HotProductDTO dto = productStatsMap.getOrDefault(productId, new HotProductDTO());
            
            if (dto.getId() == null) {
                dto.setId(productId);
                dto.setName(item.getProductName());
                dto.setImage(item.getProductImage());
                dto.setPrice(item.getPrice());
                dto.setSales(0);
                dto.setTotalAmount(BigDecimal.ZERO);
            }
            
            dto.setSales(dto.getSales() + item.getQuantity());
            dto.setTotalAmount(dto.getTotalAmount().add(item.getSubtotal()));
            
            productStatsMap.put(productId, dto);
        }
        
        // 按销售额排序，取TOP N
        return productStatsMap.values().stream()
            .sorted((a, b) -> b.getTotalAmount().compareTo(a.getTotalAmount()))
            .limit(limit)
            .collect(Collectors.toList());
    }

    /**
     * 根据时间范围获取开始时间
     */
    private LocalDateTime getStartTime(String timeRange) {
        LocalDateTime now = LocalDateTime.now();
        switch (timeRange.toLowerCase()) {
            case "today":
                return now.withHour(0).withMinute(0).withSecond(0).withNano(0);
            case "week":
                return now.minusWeeks(1);
            case "month":
                return now.minusMonths(1);
            case "all":
            default:
                return null; // 查询全部
        }
    }
}

